﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;

namespace MyPublisher.Windows.Controls
{   
    public class ShowHideGridSplitter:GridSplitter
    {
        public delegate void ShowHideStatusChangingEventHandler(object sender, ShowHideStatusChangingEventArgs e);

        public class ShowHideStatusChangingEventArgs:RoutedEventArgs
        {
            public ShowHideStatusChangingEventArgs(RoutedEvent routedEvent,bool currentStatus,bool newStatus)
                :base(routedEvent)
            {
                this.NewStatus = newStatus;
                this.CurrentStatus = currentStatus;
            }

            public bool NewStatus
            {
                get;
                private set;
            }
            public bool CurrentStatus
            {
                get;
                private set;
            }
            public bool CancelChange
            {
                get;set;
            }
        }

        public static readonly RoutedEvent HiddenStatusChangedEvent =
                            EventManager.RegisterRoutedEvent("HiddenStatusChanged", RoutingStrategy.Bubble,
                                typeof(RoutedEventHandler), typeof(ShowHideGridSplitter));
        /// <summary>
        /// The event for hidden status changed
        /// </summary>
        public event RoutedEventHandler HiddenStatusChanged
        {
            add { AddHandler(HiddenStatusChangedEvent, value); }
            remove { RemoveHandler(HiddenStatusChangedEvent, value); }
        }


        public static readonly RoutedEvent HiddenStatusChangingEvent =
                            EventManager.RegisterRoutedEvent("HiddenStatusChanging", RoutingStrategy.Bubble,
                                typeof(ShowHideStatusChangingEventHandler), typeof(ShowHideGridSplitter));
        /// <summary>
        /// The event for hidden status changing
        /// </summary>
        public event ShowHideStatusChangingEventHandler HiddenStatusChanging
        {
            add { AddHandler(HiddenStatusChangingEvent, value); }
            remove { RemoveHandler(HiddenStatusChangingEvent, value); }
        }

        /// <summary>
        /// The original width or height for current Gird Column or Grid Row
        /// </summary>
        protected GridLength OriginalWidthOrHeight
        {
            get;
            set;
        }

        public static readonly DependencyProperty HiddenProperty = DependencyProperty.Register("Hidden", typeof(Boolean),
            typeof(ShowHideGridSplitter), new PropertyMetadata(false, new PropertyChangedCallback(OnHiddenChanged)));
        /// <summary>
        /// The Hidden status
        /// True for Hide, False for show
        /// </summary>
        public bool Hidden
        {
            get
            {
                return (bool)this.GetValue(HiddenProperty);
            }
            set
            {               
                ShowHideStatusChangingEventArgs e = 
                    new ShowHideStatusChangingEventArgs(ShowHideGridSplitter.HiddenStatusChangingEvent,Hidden,value); 
                this.RaiseEvent(e);
                if (!e.CancelChange)
                {
                    this.SetValue(HiddenProperty, value);
                }
            }
        }

        public static readonly DependencyProperty ManualHandleHiddenChangedProperty = DependencyProperty.Register("ManualHandleHiddenChanged", typeof(Boolean),
            typeof(ShowHideGridSplitter), new PropertyMetadata(false));
        /// <summary>
        /// Whether user handle the hidden status changed event manually
        /// </summary>
        public bool ManualHandleHiddenChanged
        {
            get
            {
                return (bool)this.GetValue(ManualHandleHiddenChangedProperty);
            }
            set
            {
                this.SetValue(ManualHandleHiddenChangedProperty, value);
            }
        }

        private static void OnHiddenChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            ShowHideGridSplitter gridSplitter = sender as ShowHideGridSplitter;
            if (HiddenStatusChangedEvent != null)
            {
                gridSplitter.RaiseEvent(new RoutedEventArgs(ShowHideGridSplitter.HiddenStatusChangedEvent));
            }
            if (!gridSplitter.ManualHandleHiddenChanged)
            {
                gridSplitter.Toggle();
            }            
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            Image hideImage = base.GetTemplateChild("PART_HIDE") as Image;
            //hide.ToolTip = Properties.Resources.SpillterHideButton;
            if (hideImage != null)
            {
                hideImage.PreviewMouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(hideImage_PreviewMouseLeftButtonDown);
                hideImage.PreviewKeyUp += new System.Windows.Input.KeyEventHandler(hideImage_PreviewKeyUp);
            }
        }

        void hideImage_PreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == System.Windows.Input.Key.Enter || e.Key == System.Windows.Input.Key.Space)
            {
                this.Hidden = !this.Hidden;
            }
        }

        void hideImage_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            this.Hidden = !this.Hidden;
        }
       
        
        private void Toggle()
        {
            // get the parent grid control
            Grid parentGrid = this.Parent as Grid;
            if (parentGrid != null)
            {
                if (this.ResizeDirection == GridResizeDirection.Columns)
                {
                    int columnIndex = (int)this.GetValue(Grid.ColumnProperty);
                    if (Hidden)
                    {
                        // save the old width
                        OriginalWidthOrHeight = parentGrid.ColumnDefinitions[columnIndex].Width;
                        // set column width to splitter width to hide the column
                        parentGrid.ColumnDefinitions[columnIndex].Width = new GridLength(this.Width);
                    }
                    else
                    {
                        // restore the grid column to show the column
                        parentGrid.ColumnDefinitions[columnIndex].Width = OriginalWidthOrHeight;
                    }
                }
                else if (this.ResizeDirection == GridResizeDirection.Rows)
                {
                    int rowIndex = (int)this.GetValue(Grid.RowProperty);
                    if (Hidden)
                    {
                        // save the old height
                        OriginalWidthOrHeight = parentGrid.RowDefinitions[rowIndex].Height;
                        // set row height to splitter height to hide the row
                        parentGrid.RowDefinitions[rowIndex].Height = new GridLength(this.Height);
                    }
                    else
                    {
                        // restore the grid column to show the column
                        parentGrid.RowDefinitions[rowIndex].Height = OriginalWidthOrHeight;
                    }
                }                
            }
        }
    }
}
